--- id: TASK-006 title: 'Rich live game detail (box score, scorers)' status: "\U0001F3C1 Done" assignee: [] created_date: '2026-06-16 18:03' updated_date: '2026-06-18 01:17' labels: - feature dependencies: [] priority: medium ordinal: 1000 --- ## Description Extend the full-page detail view with ESPN summary endpoint (.../{sport}/{path}/summary?event={id}): goals/scorers + match events for soccer, box score for MLB/NBA/NHL/NFL. Own tea.Cmd keyed by game ID, refreshed while detail open. ## Acceptance Criteria - [x] #1 soccer detail shows goals/scorers + key events - [x] #2 detail auto-refreshes while open ## Implementation Plan 1. model: add GameDetail{Events []MatchEvent; Leaders []TeamLeaders} + MatchEvent{Clock,Type,Text,ShortText,Team string; Scoring bool; Athletes []string} + TeamLeaders{Abbr string; Leaders []Leader{Category,Athlete,Value}}. model still imports nothing internal. 2. espn: new summary.go — decode summary endpoint (keyEvents + leaders), add Client.Summary(ctx, league, eventID) returning model.GameDetail. Map soccer keyEvents->MatchEvent, leaders->TeamLeaders. 3. ui/commands.go: detailMsg{ID,Data,Err} + fetchDetail(client,league,id) cmd. 4. ui/app.go: App.detailData map[string]model.GameDetail + detailErr; handle detailMsg; on pollMsg when mode==detail also fetchDetail (auto-refresh, no new tick loop). 5. ui/update.go: on Enter fire fetchDetail; on manual refresh in detail fire fetchDetail too. 6. ui/detail.go: render eventsBlock (soccer: goals/cards/subs timeline, team-colored) and leadersBlock (other sports) below metaBlock. 7. espn test: add TestSummary against in-memory fixture (offline). ## Final Summary Added rich game detail via ESPN summary endpoint. What changed: - model: new GameDetail/MatchEvent/TeamBox/StatGroup/PlayerRow league-agnostic types (model/detail.go). - espn: summary.go with Client.Summary(ctx, league, eventID); decodes keyEvents + boxscore.players from the summary payload (types.go) and maps to GameDetail. gzip auto-handled by the http client. - ui: detailData map keyed by event ID + detailErr/detailScroll on App. fetchDetail tea.Cmd fired on Enter, on manual refresh (r), and piggybacked on the 15s poll loop while detail is open (no new ticker). detail.go renders a soccer key-event timeline (goals/cards/subs, minute-stamped, team-colored) and per-team box-score stat tables for MLB/NBA/NHL/NFL, with column-drop-to-fit. Tall pages (box scores) top-align and scroll via Up/Down; short pages stay centered. Tests: TestMapSummarySoccerEvents + TestMapSummaryBoxScore (offline fixtures). Verified live decode end-to-end against EPL (goals+assists) and NFL (full box score) with a throwaway test, then deleted it. go build/vet/test all clean. User impact: opening a game now shows scorers/key events (soccer) or full box scores (other leagues), refreshing live while open.